home *** CD-ROM | disk | FTP | other *** search
- # -*- coding: utf-8 -*-
- #
- # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- #
- # Author: Don Welch
- #
-
- # Std Lib
- import sys
- import re
- import getopt
- import os
-
- # Local
- from g import *
- import tui, utils, device
-
- USAGE_FLAG_NONE = 0x00
- USAGE_FLAG_DEVICE_ARGS = 0x01
- USAGE_FLAG_SUPRESS_G_DEBUG_FLAG = 0x02
- USAGE_FLAG_FILE_ARGS = 0x04
-
-
-
- class Module(object):
- def __init__(self, mod, title, version, doc,
- usage_data=None, avail_modes=None,
- supported_ui_toolkits=None,
- run_as_root_ok=False, quiet=False):
-
- self.mod = mod
- self.title = title
- self.version = version
- self.doc = doc
- self.usage_data = usage_data
- os.umask(0037)
- log.set_module(mod)
- self.args = []
- self.quiet = quiet
- self.lock_file = None
- prop.prog = sys.argv[0]
-
- if os.getenv("HPLIP_DEBUG"):
- log.set_level('debug')
-
- self.avail_modes = avail_modes
- if supported_ui_toolkits is not None:
- self.supported_ui_toolkits = supported_ui_toolkits
- self.num_supported_ui_toolkits = len(self.supported_ui_toolkits)
- else:
- self.supported_ui_toolkits = []
- self.num_supported_ui_toolkits = 0
-
- self.default_ui_toolkit = sys_conf.get('configure', 'ui-toolkit', 'qt4')
-
- self.num_installed_ui_toolkits = 0
- self.installed_ui_toolkits = []
- if utils.to_bool(sys_conf.get('configure', 'qt3', '0')):
- self.installed_ui_toolkits.append(UI_TOOLKIT_QT3)
- self.num_installed_ui_toolkits += 1
-
- if utils.to_bool(sys_conf.get('configure', 'qt4', '0')):
- self.installed_ui_toolkits.append(UI_TOOLKIT_QT4)
- self.num_installed_ui_toolkits += 1
-
- self.default_mode = INTERACTIVE_MODE
-
- self.num_valid_modes = 0
- if self.avail_modes is not None:
- if GUI_MODE in self.avail_modes and prop.gui_build and self.installed_ui_toolkits:
- self.num_valid_modes += 1
-
- if INTERACTIVE_MODE in self.avail_modes:
- self.num_valid_modes += 1
-
- if NON_INTERACTIVE_MODE in self.avail_modes:
- self.num_valid_modes += 1
-
- if self.avail_modes is not None:
- if INTERACTIVE_MODE in self.avail_modes:
- self.default_mode = INTERACTIVE_MODE
-
- elif NON_INTERACTIVE_MODE in self.avail_modes:
- self.default_mode = NON_INTERACTIVE_MODE
-
- if self.supported_ui_toolkits is not None and prop.gui_build and self.installed_ui_toolkits:
-
- if self.default_ui_toolkit == 'qt3' and UI_TOOLKIT_QT4 in self.supported_ui_toolkits and \
- UI_TOOLKIT_QT3 not in self.supported_ui_toolkits and INTERACTIVE_MODE in self.avail_modes:
-
- # interactive + qt4 and default is qt3 --> set to interactive (if avail) (e.g., hp-align)
- self.default_mode = INTERACTIVE_MODE
- self.default_ui_toolkit = 'none'
-
- elif (UI_TOOLKIT_QT4 in self.supported_ui_toolkits and self.default_ui_toolkit == 'qt4' and UI_TOOLKIT_QT4 in self.installed_ui_toolkits) or \
- (UI_TOOLKIT_QT3 in self.supported_ui_toolkits and self.default_ui_toolkit == 'qt3' and UI_TOOLKIT_QT3 in self.installed_ui_toolkits):
-
- self.default_mode = GUI_MODE
-
- elif self.default_ui_toolkit == 'qt3' and UI_TOOLKIT_QT3 not in self.supported_ui_toolkits:
-
- if UI_TOOLKIT_QT4 in self.supported_ui_toolkits and UI_TOOLKIT_QT4 in self.installed_ui_toolkits: # (e.g, hp-linefeedcal?)
- self.default_ui_toolkit = 'qt4'
- self.default_mode = GUI_MODE
-
- elif INTERACTIVE_MODE in self.avail_modes:
- self.default_mode = INTERACTIVE_MODE
-
- elif NON_INTERACTIVE_MODE in self.avail_modes:
- self.default_mode = NON_INTERACTIVE_MODE
-
- else:
- log.error("%s cannot be run using Qt3 toolkit." % self.mod)
- sys.exit(1)
-
- elif self.default_ui_toolkit == 'qt4' and UI_TOOLKIT_QT4 not in self.supported_ui_toolkits:
-
- if UI_TOOLKIT_QT3 in self.supported_ui_toolkits and UI_TOOLKIT_QT3 in self.installed_ui_toolkits: # (e.g., hp-unload)
- self.default_ui_toolkit = 'qt3'
- self.default_mode = GUI_MODE
-
- elif INTERACTIVE_MODE in self.avail_modes:
- self.default_mode = INTERACTIVE_MODE
-
- elif NON_INTERACTIVE_MODE in self.avail_modes:
- self.default_mode = NON_INTERACTIVE_MODE
-
- else:
- log.error("%s cannot be run using Qt4 toolkit." % self.mod)
- sys.exit(1)
-
-
- self.mode = self.default_mode
-
- #log.debug("Default ui-toolkit: %s" % self.default_ui_toolkit)
- #log.debug("Default mode: %s" % self.default_mode)
-
- if os.getuid() == 0 and not run_as_root_ok:
- log.warn("%s should not be run as root/superuser." % mod)
-
-
- def setUsage(self, include_flags=0, extra_options=None,
- extra_notes=None, see_also_list=None):
-
- if self.doc:
- self.usage_data = [(self.doc, "", "name", True)]
- else:
- self.usage_data = []
-
- summary = ['Usage:', self.mod]
- content = []
- notes = []
-
- if include_flags & USAGE_FLAG_DEVICE_ARGS == USAGE_FLAG_DEVICE_ARGS:
- summary.append('[DEVICE_URI|PRINTER_NAME]')
- content.append(utils.USAGE_ARGS)
- content.append(utils.USAGE_DEVICE)
- content.append(utils.USAGE_PRINTER)
-
- if self.avail_modes is not None and self.num_valid_modes > 1:
- summary.append('[MODE]')
- content.append(utils.USAGE_SPACE)
- content.append(utils.USAGE_MODE)
-
- if self.num_installed_ui_toolkits > 0:
- if GUI_MODE in self.avail_modes and prop.gui_build:
- content.append(utils.USAGE_GUI_MODE)
-
- if INTERACTIVE_MODE in self.avail_modes:
- content.append(utils.USAGE_INTERACTIVE_MODE)
-
- if NON_INTERACTIVE_MODE in self.avail_modes:
- content.append(utils.USAGE_NON_INTERACTIVE_MODE)
-
- # [options]
- summary.append('[OPTIONS]')
- content.append(utils.USAGE_SPACE)
- content.append(utils.USAGE_OPTIONS)
-
- if self.avail_modes is not None and GUI_MODE in self.avail_modes and \
- self.supported_ui_toolkits is not None and self.num_supported_ui_toolkits > 0 and \
- prop.gui_build and self.num_installed_ui_toolkits > 0:
-
- if UI_TOOLKIT_QT3 in self.supported_ui_toolkits and UI_TOOLKIT_QT3 in self.installed_ui_toolkits:
- content.append(utils.USAGE_USE_QT3)
-
- if UI_TOOLKIT_QT4 in self.supported_ui_toolkits and UI_TOOLKIT_QT4 in self.installed_ui_toolkits:
- content.append(utils.USAGE_USE_QT4)
-
- content.append(utils.USAGE_LOGGING1)
- content.append(utils.USAGE_LOGGING2)
- if include_flags & USAGE_FLAG_SUPRESS_G_DEBUG_FLAG != USAGE_FLAG_SUPRESS_G_DEBUG_FLAG:
- content.append(utils.USAGE_LOGGING3) # Issue with --gg in hp-sendfax
-
- # -q/--lang
- #if self.avail_modes is not None and GUI_MODE in self.avail_modes and prop.gui_build:
- # content.append(utils.USAGE_LANGUAGE)
-
- content.append(utils.USAGE_HELP)
-
- if extra_options is not None:
- for e in extra_options:
- content.append(e)
-
- # [FILES]
- if include_flags & USAGE_FLAG_FILE_ARGS:
- summary.append('[FILES]')
-
- # Notes
- if extra_notes is not None or notes:
- content.append(utils.USAGE_SPACE)
- content.append(utils.USAGE_NOTES)
-
- for n in notes:
- content.append(n)
-
- if extra_notes is not None:
- for n in extra_notes:
- content.append(n)
-
- # See Also
- if see_also_list is not None:
- content.append(utils.USAGE_SPACE)
- content.append(utils.USAGE_SEEALSO)
- for s in see_also_list:
- content.append((s, '', 'seealso', False))
-
- content.insert(0, (' '.join(summary), '', 'summary', True))
-
- for c in content:
- self.usage_data.append(c)
-
-
- def parseStdOpts(self, extra_params=None,
- extra_long_params=None,
- handle_device_printer=True,
- supress_g_debug_flag=False):
-
- params = 'l:h' # 'l:hq:'
- if not supress_g_debug_flag:
- params = ''.join([params, 'g'])
-
- long_params = ['logging=', 'help', 'help-rest', 'help-man',
- 'help-desc',
- #'lang=', 'loc=',
- 'debug', 'dbg']
-
- if handle_device_printer:
- params = ''.join([params, 'd:p:P:'])
- long_params.extend(['device=', 'device-uri=', 'printer=', 'printer-name'])
-
- if self.num_valid_modes > 1:
- if GUI_MODE in self.avail_modes and prop.gui_build:
- params = ''.join([params, 'u'])
- long_params.extend(['gui', 'ui'])
-
- if INTERACTIVE_MODE in self.avail_modes:
- params = ''.join([params, 'i'])
- long_params.extend(['interactive', 'text'])
-
- if NON_INTERACTIVE_MODE in self.avail_modes:
- params = ''.join([params, 'n'])
- long_params.extend(['noninteractive', 'non-interactive', 'batch'])
-
- if self.supported_ui_toolkits is not None and \
- self.num_supported_ui_toolkits > 1 and prop.gui_build and \
- self.avail_modes is not None and GUI_MODE in self.avail_modes:
-
- if UI_TOOLKIT_QT3 in self.supported_ui_toolkits and UI_TOOLKIT_QT3 in self.installed_ui_toolkits:
- long_params.extend(['qt3', 'use-qt3'])
-
- if UI_TOOLKIT_QT4 in self.supported_ui_toolkits and UI_TOOLKIT_QT4 in self.installed_ui_toolkits:
- long_params.extend(['qt4', 'use-qt4'])
-
- if extra_params is not None:
- params = ''.join([params, extra_params])
-
- if extra_long_params is not None:
- long_params.extend(extra_long_params)
-
- opts = None
- show_usage = None
- device_uri = None
- printer_name = None
- error_msg = []
- mode = self.default_mode
- if prop.gui_build:
- ui_toolkit = self.default_ui_toolkit
- else:
- ui_toolkit = 'none'
- lang = None
-
- try:
- opts, self.args = getopt.getopt(sys.argv[1:], params, long_params)
- except getopt.GetoptError, e:
- error_msg = [e.msg]
-
- else:
- for o, a in opts:
- if o in ('-d', '--device', '--device-uri'):
- device_uri = a
-
- elif o in ('-P', '-p', '--printer', '--printer-name'):
- printer_name = a
-
- elif o in ('-l', '--logging'):
- log_level = a.lower().strip()
- if not log.set_level(log_level):
- show_usage = 'text'
-
- elif o in ('-g', '--debug', '--dbg'):
- log.set_level('debug')
-
- elif o in ('-u', '--gui', '--ui'):
- if self.avail_modes is not None and GUI_MODE in self.avail_modes and \
- self.supported_ui_toolkits is not None and prop.gui_build:
- mode = GUI_MODE
- else:
- error_msg.append("Unable to enter GUI mode.")
-
- elif o in ('-i', '--interactive', '--text'):
- if self.avail_modes is not None and INTERACTIVE_MODE in self.avail_modes:
- mode = INTERACTIVE_MODE
- ui_toolkit = 'none'
-
- elif o in ('-n', '--non-interactive', '--batch'):
- if self.avail_modes is not None and NON_INTERACTIVE_MODE in self.avail_modes:
- mode = NON_INTERACTIVE_MODE
- ui_toolkit = 'none'
-
- elif o in ('-h', '--help'):
- show_usage = 'text'
-
- elif o == '--help-rest':
- show_usage = 'rest'
-
- elif o == '--help-man':
- show_usage = 'man'
-
- elif o == '--help-desc':
- show_usage = 'desc'
-
- elif o in ('--qt3', '--use-qt3'):
- if self.avail_modes is not None and GUI_MODE in self.avail_modes:
- if self.supported_ui_toolkits is not None and \
- UI_TOOLKIT_QT3 in self.supported_ui_toolkits and prop.gui_build and \
- UI_TOOLKIT_QT3 in self.installed_ui_toolkits:
-
- mode = GUI_MODE
- ui_toolkit = 'qt3'
- else:
- error_msg.append("%s does not support Qt3. Unable to enter GUI mode." % self.mod)
-
- elif o in ('--qt4', '--use-qt4'):
- if self.avail_modes is not None and GUI_MODE in self.avail_modes:
- if self.supported_ui_toolkits is not None and \
- UI_TOOLKIT_QT4 in self.supported_ui_toolkits and prop.gui_build and \
- UI_TOOLKIT_QT4 in self.installed_ui_toolkits:
-
- mode = GUI_MODE
- ui_toolkit = 'qt4'
- else:
- error_msg.append("%s does not support Qt4. Unable to enter GUI mode." % self.mod)
-
- #elif o in ('-q', '--lang', '--loc'):
- # if a.strip() == '?':
- # utils.log_title(self.title, self.version)
- # self.showLanguages()
- # sys.exit(0)
- # else:
- # lang = utils.validate_language(a.lower())
-
- if error_msg:
- show_usage = 'text'
-
- self.usage(show_usage, error_msg)
-
- if show_usage is not None:
- sys.exit(0)
-
- self.mode = mode
- return opts, device_uri, printer_name, mode, ui_toolkit, lang
-
-
- def showLanguages(self):
- f = tui.Formatter()
- f.header = ("Language Code", "Alternate Name(s)")
- for loc, ll in supported_locales.items():
- f.add((ll[0], ', '.join(ll[1:])))
-
- f.output()
-
-
- def usage(self, show_usage='text', error_msg=None):
- if show_usage is None:
- if not self.quiet:
- self.showTitle()
- return
-
- if show_usage == 'text':
- self.showTitle()
- log.info()
-
- if show_usage == 'desc':
- print self.doc
-
- else:
- utils.format_text(self.usage_data, show_usage, self.title, self.mod, self.version)
-
- if error_msg:
- for e in error_msg:
- log.error(e)
-
- sys.exit(1)
-
- sys.exit(0)
-
- if show_usage == 'text':
- sys.exit(0)
-
-
- def showTitle(self, show_ver=True):
- if not self.quiet:
- log.info("")
-
- if show_ver:
- log.info(log.bold("HP Linux Imaging and Printing System (ver. %s)" % prop.version))
- else:
- log.info(log.bold("HP Linux Imaging and Printing System"))
-
- log.info(log.bold("%s ver. %s" % (self.title, self.version)))
- log.info("")
- log.info("Copyright (c) 2001-9 Hewlett-Packard Development Company, LP")
- log.info("This software comes with ABSOLUTELY NO WARRANTY.")
- log.info("This is free software, and you are welcome to distribute it")
- log.info("under certain conditions. See COPYING file for more details.")
- log.info("")
-
-
- def getDeviceUri(self, device_uri=None, printer_name=None, back_end_filter=device.DEFAULT_BE_FILTER,
- filter=device.DEFAULT_FILTER, devices=None, restrict_to_installed_devices=True):
- """ Validate passed in parameters, and, if in text mode, have user select desired device to use.
- Used for tools that are device-centric and accept -d (and maybe also -p).
- Use the filter(s) to restrict what constitute valid devices.
-
- Return the matching device URI based on:
- 1. Passed in device_uri if it is valid (filter passes)
- 2. Corresponding device_uri from the printer_name if it is valid (filter passes) ('*' means default printer)
- 3. User input from menu (based on bus and filter)
-
- device_uri and printer_name can both be specified if they correspond to the same device.
-
- Returns:
- device_uri|None
- (returns None if passed in device_uri is invalid or printer_name doesn't correspond to device_uri)
- """
-
- log.debug("getDeviceUri(%s, %s, %s, %s, , %s)" %
- (device_uri, printer_name, back_end_filter, filter, restrict_to_installed_devices))
- log.debug("Mode=%s" % self.mode)
-
- scan_uri_flag = False
- if 'hpaio' in back_end_filter:
- scan_uri_flag = True
-
- device_uri_ok = False
- printer_name_ok = False
- device_uri_ret = None
-
- if devices is None:
- devices = device.getSupportedCUPSDevices(back_end_filter, filter)
- log.debug(devices)
-
- if device_uri is not None:
- if device_uri in devices:
- device_uri_ok = True
-
- elif restrict_to_installed_devices:
- log.error("Invalid device URI: %s" % device_uri)
- device_uri = None
-
- else:
- device_uri_ok = True
-
- if printer_name is not None:
- printers = device.getSupportedCUPSPrinterNames(back_end_filter, filter)
- if printer_name in printers:
- printer_name_ok = True
- printer_name_device_uri = device.getDeviceURIByPrinterName(printer_name, scan_uri_flag)
- else:
- log.error("Invalid printer name: %s" % printer_name)
- printer_name = None
-
- if device_uri is not None and printer_name is None and device_uri_ok: # Only device_uri specified
- device_uri_ret = device_uri
-
- elif device_uri is not None and printer_name is not None: # Both specified
- if device_uri_ok and printer_name_ok:
- if device_uri == printer_name_device_uri:
- device_uri_ret = device_uri
- else:
- log.error("Printer name %s and device URI %s refer to different devices." % (printer_name, device_uri))
- printer_name, printer_name = None, None
-
- elif device_uri is None and printer_name is not None and printer_name_ok: # Only printer name specified
- device_uri_ret = device.getDeviceURIByPrinterName(printer_name, scan_uri_flag)
-
- elif len(devices) == 1: # Nothing specified, and only 1 device avail.
- device_uri_ret = devices.keys()[0]
- log.info("Using device: %s\n" % device_uri_ret)
-
- if device_uri_ret is None and self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE) and len(devices):
- device_uri_ret = tui.device_table(devices, scan_uri_flag)
-
- if device_uri_ret is not None:
- user_conf.set('last_used', 'device_uri', device_uri_ret)
-
- else:
- if self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE):
- log.error("No device selected/specified or that supports this functionality.")
- sys.exit(1)
- else:
- log.debug("No device selected/specified")
-
- return device_uri_ret
-
-
- def getPrinterName(self, printer_name, device_uri, back_end_filter=device.DEFAULT_BE_FILTER,
- filter=device.DEFAULT_FILTER):
- """ Validate passed in parameters, and, if in text mode, have user select desired printer to use.
- Used for tools that are printer queue-centric and accept -p (and maybe also -d).
- Use the filter(s) to restrict what constitute valid printers.
-
- Return the matching printer_name based on:
- 1. Passed in printer_name if it is valid (filter passes) ('*' means default printer)
- 2. From single printer_name of corresponding passed in device_uri (filter passes)
- 3. User input from menu (CUPS printer list, filtered) [or if > 1 queue for device_uri]
-
- device_uri and printer_name can both be specified if they correspond to the same device.
-
- Returns:
- (printer_name|None, device_uri|None) (tuple)
- (returns None if passed in printer_name is invalid or device_uri doesn't correspond to printer_name)
- """
-
- log.debug("getPrinterName(%s, %s, %s, %s)" % (device_uri, printer_name, back_end_filter, filter))
- log.debug("Mode=%s" % self.mode)
-
- device_uri_ok = False
- printer_name_ok = False
- printer_name_ret = None
- device_uri_ret = None
-
- printers = device.getSupportedCUPSPrinterNames(back_end_filter, filter)
- log.debug(printers)
-
- if device_uri is not None:
- devices = device.getSupportedCUPSDevices(back_end_filter, filter)
- if device_uri in devices:
- device_uri_ok = True
- device_uri_ret = device_uri
- else:
- log.error("Invalid device URI: %s" % device_uri)
- device_uri = None
-
- if printer_name is not None:
- if printer_name == '*':
- from prnt import cups
- default_printer = cups.getDefaultPrinter()
- if default_printer is not None:
- printer_name_ret = default_printer
- else:
- log.error("CUPS default printer not set")
- printer_name = None
-
- else:
- if printer_name in printers:
- printer_name_ok = True
- device_uri_ret = device.getDeviceURIByPrinterName(printer_name)
- else:
- log.error("Invalid printer name")
- printer_name = None
-
- if device_uri is not None and printer_name is None and device_uri_ok: # Only device_uri specified
- if len(devices[device_uri]) == 1:
- printer_name_ret = devices[device_uri][0]
-
- elif device_uri is not None and printer_name is not None: # Both specified
- if device_uri_ok and printer_name_ok:
- if device_uri == device_uri_ret:
- printer_name_ret = printer_name
- else:
- log.error("Printer name and device URI refer to different devices.")
-
- elif device_uri is None and printer_name is not None and printer_name_ok: # Only printer name specified
- printer_name_ret = printer_name
-
- elif len(printers) == 1: # nothing specified, and only 1 avail. printer
- printer_name_ret = printers[0]
- log.info("Using printer: %s\n" % printer_name_ret)
-
- if printer_name_ret is None and self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE) and len(printers):
- printer_name_ret = tui.printer_table(printers)
-
- if printer_name_ret is not None and device_uri_ret is None:
- device_uri_ret = device.getDeviceURIByPrinterName(printer_name_ret)
-
- if device_uri_ret is not None:
- user_conf.set('last_used', 'device_uri', device_uri_ret)
-
- if printer_name_ret is not None:
- user_conf.set('last_used', 'printer_name', printer_name_ret)
-
- else:
- if self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE):
- log.error("No printer selected/specified or that supports this functionality.")
- sys.exit(1)
- else:
- log.debug("No printer selected/specified")
-
- return printer_name_ret, device_uri_ret
-
-
- def lockInstance(self, suffix=''):
- if suffix:
- ok, self.lock_file = utils.lock_app('-'.join([self.mod, suffix]))
- else:
- ok, self.lock_file = utils.lock_app(self.mod)
-
- if not ok:
- sys.exit(1)
-
-
- def unlockInstance(self):
- if self.lock_file is not None:
- utils.unlock(self.lock_file)
-